package com.dgut.courses_selecting_sys.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dgut.courses_selecting_sys.constants.RedisKey;
import com.dgut.courses_selecting_sys.entity.Dept;
import com.dgut.courses_selecting_sys.mapper.DeptMapper;
import com.dgut.courses_selecting_sys.service.IDeptService;
import com.dgut.courses_selecting_sys.utils.RedisUtil;
import com.dgut.courses_selecting_sys.utils.core.Convert;
import com.dgut.courses_selecting_sys.utils.core.StringUtils;
import com.dgut.courses_selecting_sys.vo.TreeNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yuec
 * @since 2020-08-06
 */
@Slf4j
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public List<TreeNode> getDeptData() {
        Map m = redisUtil.hmget(RedisKey.TREE_DEPT);
        Collection<TreeNode> list = m.values();
        if (list.size() != 0) {
            //从redis中取出
            return list.stream().collect(Collectors.toList());
        }
        List<TreeNode> treeNodes = new ArrayList<>();
        List<Dept> deptList = deptMapper.selectList(null);
        Map<String, Object> map = new HashMap<>();
        for (Dept dept : deptList) {
            int index = (dept.getAncestors().length() - dept.getAncestors().replaceAll(",", "").length());
            if (index < 2) {
                TreeNode treeNode = new TreeNode();
                treeNode.setId(dept.getDeptId());
                treeNode.setPid(dept.getParentId());
                treeNode.setName(dept.getDeptName());
                treeNodes.add(treeNode);
                map.put(String.valueOf(treeNode.getId()), treeNode);
            }
        }
        //加入redis中
        redisUtil.hmset(RedisKey.TREE_DEPT, map);
        return treeNodes;
    }

    //    @Cacheable(cacheNames = {RedisKey.TREE_DETAILS})
    @Override
    public List<TreeNode> getDeptDataDetails() {
        Map m = redisUtil.hmget(RedisKey.TREE_DETAILS);
        Collection<TreeNode> list = m.values();
        if (list.size() != 0) {
            //从redis中取出
            return list.stream().collect(Collectors.toList());
        }
        List<TreeNode> treeNodes = new ArrayList<>();
        List<Dept> deptList = deptMapper.selectList(null);
        Map<String, Object> map = new HashMap<>();
        for (Dept dept : deptList) {
            TreeNode treeNode = new TreeNode();
            treeNode.setId(dept.getDeptId());
            treeNode.setPid(dept.getParentId());
            treeNode.setName(dept.getDeptName());
            int index = (dept.getAncestors().length() - dept.getAncestors().replaceAll(",", "").length());
            if (index < 2) {
                treeNode.setOpen(1);
            }
            map.put(String.valueOf(treeNode.getId()), treeNode);
            treeNodes.add(treeNode);
        }
        redisUtil.hmset(RedisKey.TREE_DETAILS, map);
        return treeNodes;
    }

    //    @Caching(evict = {@CacheEvict(cacheNames = {RedisKey.TREE_DEPT}, allEntries = true),
//            @CacheEvict(cacheNames = {RedisKey.TREE_DETAILS}, allEntries = true),})
    @Override
    public boolean saveDept(Dept dept) {
        deptMapper.insert(dept);
        Integer deptId = deptMapper.selectMaxId();
        TreeNode treeNode = new TreeNode();
        treeNode.setId(deptId);
        treeNode.setPid(dept.getParentId());
        treeNode.setName(dept.getDeptName());
        int index = (dept.getAncestors().length() - dept.getAncestors().replaceAll(",", "").length());
        if (index < 2) {
            treeNode.setOpen(1);
        }
        if (index < 2 && redisUtil.hasKey(RedisKey.TREE_DEPT)) {
            redisUtil.hset(RedisKey.TREE_DEPT, String.valueOf(treeNode.getId()), treeNode);
        }
        if (index >= 2 && redisUtil.hasKey(RedisKey.TREE_DETAILS)) {
            redisUtil.hset(RedisKey.TREE_DETAILS, String.valueOf(treeNode.getId()), treeNode);
        }
        log.info("机构节点创建::创建节点->{}->节点名称->{}", dept.getDeptId(), dept.getDeptName());
        return true;
    }

    @Override
    @Cacheable(cacheNames = {"ancestorsFullName"}, key = "#dept.deptId")
    public String getAncestorsFrom(Dept dept) {
        if (StringUtils.isNotNull(dept)) {
            StringBuffer sbf = new StringBuffer();
            String[] list = dept.getAncestors().split(",");
            if (list.length > 1) {
                for (int i = 1; i < list.length; i++) {
                    sbf = sbf.append(deptMapper.selectById(Integer.valueOf(list[i])).getDeptName());
                    sbf = sbf.append("-");
                }
            }
            sbf = sbf.append(dept.getDeptName());
            return sbf.toString();
        } else {
            return "系统繁忙,查询延迟";
        }
    }

    @Override
    @Caching(evict = {@CacheEvict(cacheNames = {RedisKey.TREE_DEPT}, allEntries = true),
            @CacheEvict(cacheNames = {RedisKey.TREE_DETAILS}, allEntries = true)
            })
    public boolean updateDeptById(Dept dept) {
        redisUtil.hdel(RedisKey.DEPT, String.valueOf(dept.getDeptId()));
        log.info("机构节点更新::更新节点->{}->节点名称->{}", dept.getDeptId(), dept.getDeptName());
        Boolean result;
        if (result=Convert.toBool(deptMapper.updateById(dept))){
            redisUtil.hset(RedisKey.DEPT,String.valueOf(dept.getDeptId()),deptMapper.selectById(dept.getDeptId()));
        }
        return result;
    }

    //    @Caching(evict = {
//            @CacheEvict(value = {RedisKey.TREE_DEPT}, allEntries = true),
//            @CacheEvict(cacheNames = {RedisKey.TREE_DETAILS}, allEntries = true)})
    @Override
    public boolean removeDeptById(int deptId) {
        redisUtil.hdel(RedisKey.DEPT, String.valueOf(deptId));
        redisUtil.hdel(RedisKey.TREE_DEPT, String.valueOf(deptId));
        redisUtil.hdel(RedisKey.TREE_DETAILS, String.valueOf(deptId));
        log.warn("机构节点删除::删除节点->{}", deptId);
        return Convert.toBool(deptMapper.deleteById(deptId));
    }

    //    @Cacheable(value = {RedisKey.DEPT}, key = "#deptId", unless = "#result==null")
    @Override
    public Dept getByDeptId(int deptId) {
        if (redisUtil.hHasKey(RedisKey.DEPT, String.valueOf(deptId))) {
            return (Dept) redisUtil.hget(RedisKey.DEPT,String.valueOf(deptId));
        }
        Dept dept=deptMapper.selectById(deptId);
        redisUtil.hset(RedisKey.DEPT, String.valueOf(deptId), dept);
        return dept;
    }

}
